/* 
 * File:   InterpolacionAproximacion.cpp
 * Author: ginancm
 * 
 * Created on 18 de septiembre de 2011, 10:32 PM
 */

#include <stdlib.h>

#include "InterpolacionAproximacion.h"
#include "Lab4/InterpolacionLagrange.h"
#include <cmath>
#include <librerias/ReaderLabs.h>
//#include <>
#include <cstdio>
#include <cstring>
#include <deque>
#include "librerias/jama125/jama_lu.h"
#include <float.h>

using namespace std;
InterpolacionAproximacion::InterpolacionAproximacion(int anoSelect, int tamFileIn, int tamInterpol, const char* polyInterp, int tamAleatorios, int ajusteAleatorio)
:ReaderLabs("datosPractica.csv","salida.txt"){
    
    this->gradPolyAprox=1;
//    Poner setters para los nombers de los archivos
//  
    this->ano=anoSelect;
    this->tam_entrada=tamFileIn;
    this->tam_ajuste=tamInterpol;
    this->tipoPoly=new char [10];
    strcpy(tipoPoly, polyInterp);
    this->tam_aleatorios=tamAleatorios;
    this->tam_ajusteRandom=ajusteAleatorio;
    this->errorAproximacion=0;
    this->bondadAproximacn=0;
    //Creo arreglos
    //
    this->array_datosX= new double [tam_entrada];
    this->array_datosY= new double [tam_entrada];
   
    this->array_xRandom= new double [tam_aleatorios]; 
    this->array_fdrand= new double [tam_aleatorios];
    
    array_coefAprox=TNT::Array1D<long double>();
    array_errorOtro=NULL;
    array_interpAprox=NULL;
    array_interpOtro=NULL;
    array_xSelect=NULL;
    array_ySelect=NULL;
    mat_sumatorias=NULL;
}

InterpolacionAproximacion::~InterpolacionAproximacion() {
    delete tipoPoly;
    tipoPoly=NULL;
    
//    //Borro vector sumas
//    delete vectSumas;
    //Delete arrays
    delete array_datosX;
    array_datosX=NULL;
    delete array_datosY;
    array_datosY=NULL;
    delete array_xRandom;
    array_xRandom=NULL;
    delete array_fdrand;
    array_fdrand=NULL;
    
    array_coefAprox.~Array1D();
    delete array_errorOtro;
    array_errorOtro=NULL;
    delete array_interpAprox;
    array_interpAprox=NULL;
    delete array_interpOtro;
    array_interpOtro=NULL;
    delete array_xSelect;
    array_xSelect=NULL;
    delete array_ySelect;
    array_ySelect=NULL;
}

void InterpolacionAproximacion::leer(){
    char * nombre=NULL;
    nombre=getNameFile("Input");
    FILE * ptr_archivo= fopen((const char *)nombre, "r+");
    int int_TmpX, int_TmpY;
    int cols=3;
    
    int_TmpX=0;
    int_TmpY=0;
    
    if(ptr_archivo!=NULL)
    {
        char str [100];
        char str2[100];
        int columnaAno;
        //Leo las primeras filas con caracteres de texto
        //
        for (int i =0; i<3;i++){
        
            fscanf(ptr_archivo,"\"%s ", str);
            fscanf(ptr_archivo,"%d", &int_TmpX);
            if(int_TmpX==ano) {
                columnaAno=i;
            }if (i==2)fscanf(ptr_archivo,"%s\n", str2);
        }
        fscanf(ptr_archivo,"%s",str);
        //Leo las filas con caracteres de numericos separadas por comas
        //
        for(int idFila=0;idFila<tam_entrada;idFila++)
        {
            for(int idCol=0;idCol<cols;idCol++)
            {
                fscanf(ptr_archivo,"%d;", &int_TmpX);
                fscanf(ptr_archivo,"%d;", &int_TmpY);
                if(idCol==columnaAno){
                    array_datosX[idFila]=(double)int_TmpX;
                    array_datosY[idFila]=(double)int_TmpY;
                }
            }
        }
    }
    else cout<<" No existe el archivo"<<endl;
    
    delete nombre;
    nombre=NULL;
}

void InterpolacionAproximacion::escogerDatosInter(char literal){
    
    int tamano=0; //tamaño del original
    int ajuste=0; //tamaño del ajuste
        double * array_datosTmpX;
        double * array_datosTmpY;
    
    this->punto=literal;
    //Selecciono parametros para la selcción deacuerdo a si es el punto aleatorio o no
    //
    if(literal=='B'){
        
        tamano=tam_aleatorios;
        ajuste=tam_ajusteRandom;
    } else{
        tamano=tam_entrada;
        ajuste=tam_ajuste;
    }
    
    //creo arreglos e init
    //
    array_datosTmpX= new double [tamano];
    array_datosTmpY= new double [tamano];
    
    if(flags!=NULL)//   Reseteo las banderas de ser necesario
    {
        delete flags;
        flags=NULL;
    }
    
    if(array_xSelect!=NULL && array_ySelect!=NULL)//   Reseteo las arreglos de ser necesario
    {
        delete array_xSelect;
        delete array_ySelect;
        array_xSelect=NULL;
        array_ySelect=NULL;
    }
    flags= new bool[tamano];
    //Array de datos seleccionados
    //
    array_xSelect=new double [ajuste];
    array_ySelect= new double [ajuste];
    //Seteo los valores iniciales para los arreglos necesarios
    //
    for(int i=0;i<tamano;i++)
    {
        if(literal=='B'){
            array_datosTmpX[i]=array_xRandom[i];
            array_datosTmpY[i]=array_fdrand[i];
            
        }else{
            array_datosTmpX[i]=array_datosX[i];
            array_datosTmpY[i]=array_datosY[i];
        }
        
        flags[i]=false;
    }
    //Escojo los datos
    //
    int factor=(int)ceil((double)tamano/(double)ajuste); //factor resultante de del tamaño y el ajuste


    bool yaEsta = true;
    int aleatorio=0;
    srand(time(NULL));
    //Escojo los a interpolar, segun el aleatorio
    //
    for(int idfils=0; idfils < ajuste; idfils++)
    {
        aleatorio=idfils*factor+idfils;

        if(aleatorio>=tamano)
        {
            while(yaEsta)
            {
                aleatorio = rand()%tamano;
                yaEsta=flags[aleatorio];             
            }
            yaEsta=true;
//            flags[aleatorio]=true;
        }
//        else
//        {
                flags[aleatorio]=true;
//        }
        array_xSelect[idfils]=array_datosTmpX[aleatorio];
        array_ySelect[idfils]=array_datosTmpY[aleatorio];
//        cout<<"Xsel: "<<array_xSelect[idfils]<<", Ysel: "<<array_ySelect[idfils]<<endl;
    }
    //Borro arreglos temporales
    //
    delete array_datosTmpX;
    delete array_datosTmpY;
    array_datosTmpX=NULL;
    array_datosTmpY=NULL;
}

void InterpolacionAproximacion::ordenarDatosAInterpolar(){
//    Insertion
    int i, j;
    double tmpX, tmpY;
    int tam_ajuste=0;
    if(punto=='B')tam_ajuste=this->tam_ajusteRandom;
    else tam_ajuste=this->tam_ajuste;
    
    for(i=1;i<tam_ajuste;i++)
    {
        //Ordeno primer array
        //
        tmpX=array_xSelect[i];
        tmpY=array_ySelect[i];
        j=i-1;
        while(j >= 0)
        {
            if(array_xSelect[j] > tmpX)
            {
                array_xSelect[j+1] = array_xSelect[j];
                array_ySelect[j+1] = array_ySelect[j];
                j--;
            }else break;
        }
        array_xSelect[j+1] = tmpX;
        array_ySelect[j+1] = tmpY;
    }
}

void InterpolacionAproximacion::calcularOtroPolinomio(){
    InterpolacionLagrange * ptrLagrange= new InterpolacionLagrange();
    ptrLagrange->setDatos(this->array_datosX, this->array_datosY,this-> tam_entrada);
    ptrLagrange->setSeleccion(this->array_xSelect, this->array_ySelect, this->tam_ajuste, this->flags);
    string tipo= (const char *) tipoPoly;

    if(tipo=="Lagrange")
    {
        ptrLagrange->calcularPolyLagrange();
    }
    else{
        ptrLagrange->calcularCoeficientesNewton();
        ptrLagrange->calcularPolyNewton();
    }

    this->obj_polyComp=ptrLagrange->getPoly((const char *) tipoPoly);
//    obj_polyComp.imprimirPolinomio();cout<<endl;
//    ptrLagrange=NULL;
}

void InterpolacionAproximacion::calcularSumatorias(){
    int gradoSumatorias=2*gradPolyAprox;
    long double sumatoria=0;
    long double sumatoriaB=0;
    int contGrado=0;
    vector<long double>::iterator iterador;

    if(vectSumas.size()==0)
    {
//        vectSumas= vector<long double>(gradoSumatorias,0);
        
        contGrado=1;
        //Lleno el vector
        //
//        for(iterador=vectSumas.begin();iterador<vectSumas.end()-1;iterador++)
        while(contGrado<=gradoSumatorias)
        {
            sumatoria=0;
            sumatoriaB=0;
            //Calculo la sumatoria
            //
            for(int nTermino=0;nTermino<tam_ajuste;nTermino++)
            {
                sumatoria=sumatoria+pow((long double)array_xSelect[nTermino],contGrado);
            }
            vectSumas.push_back(sumatoria);
            contGrado++;
        }

    }else{
        int sumsCalculadas=vectSumas.size();
        contGrado=sumsCalculadas+1;
        int numSumsFaltantes=gradoSumatorias-sumsCalculadas;
        
        //Lleno las sumatorias faltantes en el vector 
        //
        for(int iFaltante=0;iFaltante<numSumsFaltantes;iFaltante++){
            //Calculo Sumatoria
            //
            for(int nTermino=0;nTermino<tam_ajuste;nTermino++)
            {
                sumatoria=sumatoria+pow((long double)array_xSelect[nTermino],contGrado);
            }
            contGrado++;
            vectSumas.push_back(sumatoria);
        }
        
    }
    
    //Lleno el vector sumas B
    //
    if(vectsumasB.size()==0)
    {
        for(int i=0;i<gradPolyAprox+1;i++)
        {
            sumatoriaB=0;
            //Calculo sumatoria
            for(int nTermin=0;nTermin<tam_ajuste;nTermin++){
                sumatoriaB=sumatoriaB+((long double)array_ySelect[nTermin]*pow((long double)array_xSelect[nTermin], i));
            }
            
            vectsumasB.push_back(sumatoriaB);
        }
            
    }
    else{
        //Lleno las sumatorias faltantes en el vector 
        //
//        for(int iFaltante=0;iFaltante<numSumsFaltantes;iFaltante++){
        sumatoriaB=0;   
        //Calculo Sumatoria
        //
        int grado=vectsumasB.size();
        for(int nTermino=0;nTermino<tam_ajuste;nTermino++)
        {
                    sumatoriaB=sumatoriaB+((long double)array_ySelect[nTermino]*pow((long double)array_xSelect[nTermino], grado));
        }
        
        vectsumasB.push_back(sumatoriaB);
//        }
        
    }
    
    //Imprimo paa verificar
    //
//    contGrado=1;
//    for(iterador=vectSumas.begin();iterador<vectSumas.end();iterador++)
//    {
//        printf("Sumatoria Grado %d = %f \n",contGrado,(double)*iterador);        
//        contGrado++;
//    } 
}

void InterpolacionAproximacion::setGradoPolyAprox(int gradoNuevo){
    this->gradPolyAprox=gradoNuevo;
}

void InterpolacionAproximacion::escribirMatrizA(){
    int tamFila=gradPolyAprox+1;
//    if(mat_sumatorias.dim1()!=0) mat_sumatorias.~Array2D();
    mat_sumatorias= Array2D<long double>(tamFila,tamFila);
    long double valorTmp;
    //Lleno matriz con las sumatorias que hay hasta ahora
    //
    for(int i=0;i<tamFila;i++)
    {
        
//        printf("|  ");
        for(int j=0;j<tamFila;j++)
        {
            if(i==0 && j==0) valorTmp=(long double)tam_ajuste;
            else{
                valorTmp=vectSumas[i+j-1];                
            }
            mat_sumatorias[i][j]=valorTmp;
//            printf("%Lf\t",mat_sumatorias[i][j]);
        }
//        printf("|  | a%d |=| %Lf\t|\n",i, vect_b[i]);
    }
}

void InterpolacionAproximacion::escribirVectorB(){
    ///vect_b y vectSumasB son del mismo tamaño, vectsumasB es de tamaño dinámico
    vect_b=TNT::Array1D<long double>(vectsumasB.size());
    vector<long double>::iterator iterar=vectsumasB.begin();
    int cont=0;
    for (iterar; iterar<vectsumasB.end();iterar++)
    {
        vect_b[cont]=*iterar;
        cont++;
    }
}

void InterpolacionAproximacion::calcularPolyAprox(){
    //Determino los valores de las constantes a
    //
    JAMA::LU<long double>original=JAMA::LU<long double>(mat_sumatorias);
//    if(array_coefAprox.dim()!=0)array_coefAprox.~Array1D();
    
    if((bool)original.isNonsingular())
    {
        array_coefAprox=original.solve(vect_b);
    }
    //Imprimo para verificar
    //
    int tamArray=array_coefAprox.dim();
    obj_polyAprox.resetPolinomio();
    for(int i=0;i<tamArray;i++)
    {
        obj_polyAprox.crearNodoPolinomio(array_coefAprox[i],i);
//        printf("a%d = %Lf\n",i,array_coefAprox[i]);
    }
//    obj_polyAprox.imprimirPolinomio(); cout<<endl;
}

void InterpolacionAproximacion::calcularErrorAprox(){
    long double sumaTmp=0;
    long double diferencia=0;
    for(int i=0;i<tam_ajuste;i++)
    {
        diferencia=(long double)this->array_ySelect[i]-(long double)obj_polyAprox.evaluarPolinomio(array_xSelect[i]);
        sumaTmp=sumaTmp+pow(diferencia, 2);
    }
    this->errorAproximacion=sumaTmp;
//    printf("Error de Aprox: %Lf\n",errorAproximacion);
}

void InterpolacionAproximacion::calcularBondadAprox(){
    long  double sumatDividendo=0;
    long double diferencia=0;
    long double sumatDivisor=0;
    long double promedioY=0;
    
    //Calculo promedio
    //    
    for(int i=0;i<tam_ajuste;i++)
    {
        promedioY=promedioY+array_ySelect[i];
    }
    promedioY=promedioY/(long double)tam_ajuste;
    
    //Calculo sumatorias
    //
    for(int i=0;i<tam_ajuste;i++)
    {
        diferencia=obj_polyAprox.evaluarPolinomio((long double)this->array_xSelect[i])-promedioY;
        sumatDividendo=sumatDividendo+pow(diferencia,2);
        diferencia=(long double)array_ySelect[i]-promedioY;
        sumatDivisor=sumatDivisor+pow(diferencia,2);
    }
    this->bondadAproximacn=sumatDividendo/sumatDivisor;
//    cout<<"Bondad:"<<this->bondadAproximacn<<endl;
}

long double InterpolacionAproximacion::getBondad(){
    return bondadAproximacn;
}

Polinomio  InterpolacionAproximacion::getPolinomioAprox(){
    return  obj_polyAprox;
}

long double InterpolacionAproximacion::getErrorAprox(){
    return errorAproximacion;
}

void InterpolacionAproximacion::determinarPolinomioAprox(){
    int cont=0;
    long double bondMax=0;
    long double errorMin=LDBL_MAX;
    int grado=0;
    long double bondTmp=0;
    long double errorTmp=0;
    Polinomio objPoliTmp;
    int gradoMax=0;
    while(cont<10)
    {
        grado++;
//        cout<<"Grado: "<<grado;
        this->setGradoPolyAprox(grado);
        this->calcularSumatorias();
        this->escribirVectorB();
        this->escribirMatrizA();
        this->calcularPolyAprox();
        this->calcularErrorAprox();
        this->calcularBondadAprox();
        bondTmp=this->getBondad();
        errorTmp=this->getErrorAprox();
//        cout<<", Bondad: "<<bondTmp<<", Error: "<<errorTmp<<endl;
        if(abs((long double)1.0-bondMax)>abs((long double)1.0-bondTmp)&&errorMin>errorTmp/*(bondTmp<=1.0&&bondTmp>=0.0)*/){
            bondMax=bondTmp;
            objPoliTmp=this->getPolinomioAprox();
            errorMin=errorTmp;
            gradoMax=grado;
            cont=0;
        }else cont++;
        
    }
    this->setGradoPolyAprox(gradoMax);
//    cout<<"Grado Max Bondad: "<<gradoMax<<endl;
//    cout<<"Bondad Max: "<<bondMax<<endl;
//    cout<<"Error Min: "<<errorMin<<endl;
    this->bondadAproximacn=bondMax;
    this->errorAproximacion=errorMin;
    this->obj_polyAprox=objPoliTmp;
//    objPoliTmp.imprimirPolinomio(); cout<<endl;
}

//Evaluo los datos y calculos los errores y la bondad para los datos a analizar
//
void InterpolacionAproximacion::evaluarDatos(){

//    obj_polyNewtn.resetPolinomio();
//    obj_polyNewtn.crearNodoPolinomio(1,1);
    int tamDatos=0; //Tamaño del conjunto de datos a evaluar
    int tamResults=0;    
    int idFilaEvaluacion=0;//Fila en la cual se está evaluando en el array de respuestas
    long double promYBondPrueb=0;//para el calculo de la bondad sobre los datos de prueba
    long double sumatErrorPrueb=0;
    //Verifico si es para el punto uno o dos
    //
    if(this->punto=='B'){//punto dos
        tamDatos=tam_aleatorios;
        tamResults=tam_aleatorios-tam_ajusteRandom;
    }
    else{//punto uno
        tamDatos=tam_entrada;
        tamResults=tam_entrada-tam_ajuste;
        if(array_interpOtro!=NULL){
            delete array_interpOtro;
            array_interpOtro=NULL;
            delete array_errorOtro;
            array_errorOtro=NULL;
        }
        array_interpOtro=new long double [tamResults];
        array_errorOtro=new long double [tamResults];
    }
    
    //Empiezo a calcular los resultados
    //
    if(array_interpAprox!=NULL){
        delete array_interpAprox;
        array_interpAprox=NULL;
    }
    array_interpAprox=new long double [tamResults];
    long double xtmp=0;
    long double ytmp=0;
    for(int i=0;i<tamDatos;i++)
    {
//        cout<<flags[i]<<", ";
        if(!flags[i]){
            if(punto=='B'){
                xtmp=(long double)array_xRandom[i];
                ytmp=(long double)array_fdrand[i];
            }
            else {
                xtmp=(long double)array_datosX[i];
                ytmp=(long double)array_datosY[i];
            }
            promYBondPrueb+=ytmp;//Necesario para el calculo de bondad

//            cout<<"idFila: "<<idFilaEvaluacion<<", "<<(double)obj_polyComp.evaluarPolinomio(xtmp)<<"\n";
//            cout<<"idFila: "<<idFilaEvaluacion<<", "<<(double)obj_polyAprox.evaluarPolinomio(xtmp)<<"\n";
            array_interpAprox[idFilaEvaluacion]=obj_polyAprox.evaluarPolinomio(xtmp);//Evalulo el punto x en el polinomio de aproximación.
            sumatErrorPrueb+=pow((ytmp-array_interpAprox[idFilaEvaluacion]), 2);//Hago sumatoria para el error en los puntos
            
            if(punto=='A') {
                array_interpOtro[idFilaEvaluacion]=obj_polyComp.evaluarPolinomio(xtmp);
                array_errorOtro[idFilaEvaluacion]=abs(ytmp-array_interpOtro[idFilaEvaluacion]);
            }
            idFilaEvaluacion++;
        }
    }
    promYBondPrueb=promYBondPrueb/(long double)tamResults;
    this->errorAproxDatsPrueb=sumatErrorPrueb;//Guardo el error
    
    //Calculo bondad sobre los datos de prueba
    //
    long double divisor=0;
    long double dividendo=0;
    idFilaEvaluacion=0;
    for(int i=0;i<tamDatos;i++)
    {
//        cout<<flags[i]<<", ";
        if(!flags[i]){
            if(punto=='B'){
                xtmp=(long double)array_xRandom[i];
                ytmp=(long double)array_fdrand[i];
            }
            else {
                xtmp=(long double)array_datosX[i];
                ytmp=(long double)array_datosY[i];
            }
            
            dividendo+=pow((array_interpAprox[idFilaEvaluacion]-promYBondPrueb),2);
            divisor+=pow((ytmp-promYBondPrueb),2);
            idFilaEvaluacion++;
        }
    }
    
    this->bondadAproxDatsPrueb=dividendo/divisor;
    
    idFilaEvaluacion=0;
//    cout<<"Tipo Calculo: "<<punto<<endl;
//    cout<<"Bondad Px: "<<this->bondadAproximacn<<",  Errror Px: "<<this->errorAproximacion<<", "<<endl;
////    obj_polyComp.imprimirPolinomio();
////    cout<<endl;
//    for(int i=0;i<tamDatos;i++)
//    {
//        if(!flags[i]){
//            if(punto=='A'){
////                printf("X: %d, f(x): %d, Aprox(x): %Lf, %s(x): %Lf\n",array_datosX[i],array_datosY[i],array_interpAprox[idFilaEvaluacion],(const char*)tipoPoly,array_interpOtro[idFilaEvaluacion]);
//                cout<<"x: "<<array_datosX[i]
//                        <<", f(x): "<<array_datosY[i]
//                        <<", Aprox(x): "<<array_interpAprox[idFilaEvaluacion]<<", "
//                        <<tipoPoly<<"(x): "<<array_interpOtro[idFilaEvaluacion]<<endl;
//            }else cout<<"x: "<<array_xRandom[i]<<", Aprox(x): "<<array_interpAprox[idFilaEvaluacion]<<", f(x): "<<array_fdrand[i]<<endl; 
//            
//            idFilaEvaluacion++;
//        }
//    }
}

bool isIn(double * array, int n,double val){
    for(int i=0;i<n;i++)
    {
        if(array[i]==val) return true;
    }
    return false;
}

bool isIn(int * array, int n,int val){
    for(int i=0;i<n;i++)
    {
        if(array[i]==val)return true;
    }
    return false;
}

void InterpolacionAproximacion::inicializarDatosAleatorios(){
    srand( time(NULL) );
    double decimal=0.0;
    bool esta=true;
    for(int i=0;i<tam_aleatorios;i++){
        while(esta)
        {
            decimal=(double)rand()/(double)RAND_MAX;
            decimal=decimal*10.0;
            decimal=decimal*pow(-1.0, rand());
            esta=isIn(array_xRandom,tam_aleatorios,decimal);
        }
        esta=true;
        array_xRandom[i]=decimal;
        array_fdrand[i]=pow(-1.0, rand())*((double)rand()/(double)RAND_MAX)*100.00;
        
    }
    //Los ordeno por el valor de X
    //
    int j;
    double tmpX, tmpY;
    for(int i=1;i<tam_aleatorios;i++)
    {
        //Ordeno primer array
        //
        tmpX=array_xRandom[i];
        tmpY=array_fdrand[i];
        j=i-1;
        while(j >= 0)
        {
            if(array_xRandom[j] > tmpX)
            {
                array_xRandom[j+1] = array_xRandom[j];
                array_fdrand[j+1] = array_fdrand[j];
                j--;
            }else break;
        }
        array_xRandom[j+1] = tmpX;
        array_fdrand[j+1] = tmpY;
    }
//    for(int i=1;i<tam_aleatorios;i++)
//    {
//        cout<<"X: "<<array_xRandom[i]<<", Y: "<<array_fdrand[i]<<endl;
//    }
}

void InterpolacionAproximacion::escribirResultado1()
{
    int contResul=0;
    int x_entrada, y_esperado;
    long double y_salida, y_salidaOtro, error_otro;//Y salidas para aproximacion y lagrange o Newton, respectivamente
    
    this->abrir("Output");
    escribir("!!!!!Literal A: Por Aproximacion y %s para %d!!!!!!!!!!!!!!!!\n", (const char*)tipoPoly,this->ano);
    escribir("!!!!!Métricas para los 20 datos con los que se interpoló\n");
    escribir("G; Ba; Ra; \n"); //G=grado polinomio obtenido, Ba = bondad de ajuste, Ra=error
    escribir("%d; %Lf; %Lf;\n", gradPolyAprox, this->getBondad(), this->getErrorAprox());
    //G=grado polinomio obtenido, BAnalizar = bondad de ajuste para los datos a nalizar, RAnalizar=error para los datos a analizar
    //
    escribir("!!!!!Métricas para los datos restantes los cuales hay que analizar\n");
    escribir("G; BAnalizar; RAnalizar; \n"); 
    escribir("%d; %Lf; %Lf;\n", gradPolyAprox, bondadAproxDatsPrueb, errorAproxDatsPrueb);
    escribir("X; Y; Pa(X); Px(X); EPx(x);\n");
    for(int i=0;i<tam_entrada;i++)
    {
        x_entrada=array_datosX[i];
        y_esperado=array_datosY[i];
        if(!flags[i])
        {
            error_otro=array_errorOtro[contResul];
            y_salida=array_interpAprox[contResul];
            y_salidaOtro=array_interpOtro[contResul];
            escribir("%d; %d; %Lf; %Lf; %Lf; \n", x_entrada, y_esperado, y_salida, y_salidaOtro,error_otro);
            contResul++;
        }
        else{
            y_salida=obj_polyAprox.evaluarPolinomio((long double)x_entrada);
            y_salidaOtro=obj_polyComp.evaluarPolinomio((long double)x_entrada);
            escribir("!!!!!%d; %d; %Lf; %Lf; %Lf; \n", x_entrada, y_esperado, y_salida, y_salidaOtro, abs(y_esperado-y_salidaOtro));
        }
     }
    contResul=0;
}

void InterpolacionAproximacion::escribirResultado2(){
    int contResul=0;
    double x_entrada, y_esperado;
    long double y_salida;//Y salidas para aproximacion y lagrange o Newton, respectivamente
    this->nombreOutput="salidaB.txt";
    this->abrir("Output");
    escribir("!!!!!Literal B: Por Aproximacion!!!!!!!!!!!!!!!!\n", (const char*)tipoPoly,this->ano);
    escribir("!!!!!Métricas para los 20 datos con los que se interpoló\n");
    escribir("G; Ba; Ra; \n"); //G=grado polinomio obtenido, Ba = bondad de ajuste, Ra=error
    escribir("%d; %Lf; %Lf;\n", gradPolyAprox, this->getBondad(), this->getErrorAprox());
    //G=grado polinomio obtenido, BAnalizar = bondad de ajuste para los datos a nalizar, RAnalizar=error para los datos a analizar
    //
    escribir("!!!!!Métricas para los datos restantes los cuales hay que analizar\n");
    escribir("G; BAnalizar; RAnalizar; \n"); 
    escribir("%d; %Lf; %Lf;\n", gradPolyAprox, bondadAproxDatsPrueb, errorAproxDatsPrueb);
    escribir("X; Y; Pa(X)\n");
    for(int i=0;i<tam_aleatorios;i++)
    {
        x_entrada=array_xRandom[i];
        y_esperado=array_fdrand[i];
//        cout<<flags[i]<<endl;
        if(!flags[i])
        {
            y_salida=array_interpAprox[contResul];
            escribir("%f; %f; %Lf \n", x_entrada, y_esperado, y_salida);
            contResul++;
        }
        else{
            y_salida=obj_polyAprox.evaluarPolinomio((long double)x_entrada);
            escribir("!!!!!%f; %f; %Lf \n", x_entrada, y_esperado, y_salida);
        }
     }
    contResul=0;
}